#-*- encoding: utf-8 -*-
'''
Created on 2011-5-1

@author: Bob
'''
from jxgame.globals.GlobalDef import INVALID_CHAIR, GS_FREE, US_READY
from jxgame.game.land.Cmd import SUB_S_GAME_END, SUB_S_GAME_START,\
    SUB_S_OUT_CARD, SUB_S_LAND_SCORE, SUB_S_PASS_CARD, SUB_S_UserDouble,\
    SUB_S_SEND_CARD, GS_LAND_FREE, GS_LAND_SCORE, GS_LAND_PLAYING,\
    SUB_C_USER_DOUBLE, GAME_PLAYER, SUB_C_LAND_SCORE, SUB_C_PASS_CARD,\
    SUB_C_OUT_CART
from jxgame.proto.land_pb2 import CMD_S_StatusFree, CMD_S_StatusScore,\
    CMD_S_StatusPlay, CMD_C_UserDouble, CMD_S_UserDouble, CMD_S_GameEnd,\
    CMD_S_PassCard, CMD_S_OutCard, CMD_S_GameStart, CMD_S_LandScore,\
    CMD_S_SendAllCard, CMD_C_LandScore, CMD_C_OutCard
from jxgame.server.gameservice.ServerUser import ServerUser
from random import randint
from jxgame.game.land.GameLogic import NORMAL_COUNT, ST_ORDER, GameLogic
from jxgame.server.gameservice.AIUser import AIUser

########################_#######################_#######################
#辅助时间
TIME_LESS               = 1                                    #最少时间
TIME_DISPATCH           = 5                                    #发牌时间

#游戏时间
TIME_OUT_CARD           = 3                                    #出牌时间
TIME_START_GAME         = 4                                    #开始时间
TIME_CALL_SCORE         = 3                                    #叫分时间

#游戏时间
IDI_ANDROID_ITEM_SINK   = 500
IDI_OUT_CARD            = (IDI_ANDROID_ITEM_SINK+0)            #出牌时间
IDI_START_GAME          = (IDI_ANDROID_ITEM_SINK+1)            #开始时间
IDI_CALL_SCORE          = (IDI_ANDROID_ITEM_SINK+2)            #叫分时间

########################_#######################_#######################
#机器人类

class AIUserSink:
    #扑克变量
    TurnCardCount       = 0                     #出牌数目
    TurnCardData        = []                    #出牌列表
    OutCardUser         = []                    #出牌玩家
    BankerUser          = 0                     #地主玩家

    TurnIndex           = 0                     #轮
    UserDouble          = 0                     #用户加倍

    #手上扑克
    HandCardCount       = 0                     #扑克数目
    HandCardData        = []                    #手上扑克
    CurrentLandScore    = 0                     #已叫分数

    #控件变量
    game_logic          = None                  #游戏逻辑
    ai_user             = None                  #用户接口
    
    def __init__(self):
        self.TurnCardCount = 0
        self.TurnCardData = []
        self.OutCardUser = INVALID_CHAIR
        self.BankerUser = INVALID_CHAIR
        self.HandCardCount = 0
        self.HandCardData = []
        self.CurrentLandScore = 255
        self.ai_user = AIUser()
        self.game_logic = GameLogic()

    ########## 游戏事件 ########## 
    #时间消息
    def OnEventTimer(self, timer_id):
        if timer_id == IDI_START_GAME:
            self.ai_user.SendUserReady(None,0)
        elif timer_id == IDI_CALL_SCORE:
            cmd = CMD_C_LandScore()
            cmd.land_score=self.game_logic.LandScore(self.ai_user.chair_id,self.CurrentLandScore)
            self.ai_user.SendSocketData(SUB_C_LAND_SCORE,cmd)
        elif timer_id == IDI_OUT_CARD:
            out_card_result = self.game_logic.SearchOutCard(self.HandCardData,self.TurnCardData,self.OutCardUser,self.ai_user.chair_id)
            #牌型合法判断
            if out_card_result.card_count>0 and self.game_logic.GetCardType(out_card_result.result_card):
                pass
            #先出牌不能为空
            if self.TurnCardCount==0:
                if out_card_result.card_count==0:
                    out_card_result.card_count=1
                    out_card_result.result_card[0]=self.HandCardData[self.HandCardCount-1]
            #结果判断
            if out_card_result.card_count>0:
                if self.TurnCardCount>0 and not self.game_logic.CompareCard(self.TurnCardData, out_card_result.result_card):
                    assert False
                    #放弃出牌
                    self.ai_user.SendSocketData(SUB_C_PASS_CARD)
                    return True
                self.HandCardCount-=out_card_result.card_count
                self.game_logic.RemoveCard(out_card_result.result_card, self.HandCardData)
                cmd = CMD_C_OutCard()
                cmd.card_count = out_card_result.card_count
                cmd.card_data = out_card_result.result_card
                self.ai_user.SendSocketData(SUB_C_OUT_CART,cmd)
            else:
                self.ai_user.SendSocketData(SUB_C_PASS_CARD)
            return True
        return False
    #游戏消息
    def OnEventGameMessage(self, SubCmdID, CmdData):
        CALL_MAP = {
            SUB_S_SEND_CARD: self.OnSubSendCard,
            SUB_S_LAND_SCORE: self.OnSubCallScore,
            SUB_S_GAME_START: self.OnSubGameStart,
            SUB_S_GAME_END: self.OnSubGameEnd,
            SUB_S_OUT_CARD: self.OnSubOutCard,
            SUB_S_PASS_CARD: self.OnSubPassCard,
            SUB_S_UserDouble: self.OnSubUserDouble }
        return CALL_MAP[SubCmdID](CmdData)
    
    #游戏消息
    def OnEventFrameMessage(self):
        return True

    #场景消息
    def OnEventGameScene(self, GameStatus, LookonOther, CmdData):
        if GameStatus == GS_LAND_FREE:
            cmd = CMD_S_StatusFree()
            cmd.ParseFromString(CmdData)
            
            serverUser = ServerUser() #TODO
            if serverUser.userData.UserStatus != US_READY:
                elapse = randint(0, TIME_START_GAME) + TIME_LESS
                self.ai_user.SetGameTime(IDI_START_GAME, elapse)
            return True
        elif GameStatus == GS_LAND_SCORE:
            cmd = CMD_S_StatusScore()
            cmd.ParseFromString(CmdData)
            self.HandCardCount = NORMAL_COUNT
            self.HandCardData = cmd.card_data
            #叫分设置
            if self.ai_user.chair_id == cmd.current_user:
                elapse = randint(0, TIME_CALL_SCORE) + TIME_LESS
                self.ai_user.SetGameTime(IDI_CALL_SCORE, elapse)
            return True
        elif GameStatus == GS_LAND_PLAYING:
            cmd = CMD_S_StatusPlay
            cmd.ParseFromString(CmdData)
            self.TurnCardCount = cmd.turn_card_count
            self.TurnCardData = cmd.turn_card_data
            self.HandCardCount = NORMAL_COUNT
            self.HandCardData = cmd.card_data
            
            meChairID = self.ai_user.chair_id
            if(cmd.current_user == meChairID):
                elapse = randint(0, TIME_OUT_CARD) + TIME_LESS
                self.ai_user.SetGameTime(IDI_OUT_CARD, elapse)
            return True
        assert False
        return False
    ########## 用户事件 ##########
    #用户进入 
    def OnEventUserEnter(self):
        pass

    #用户离开
    def OnEventUserLeave(self):
        pass

    #用户积分
    def OnEventUserScore(self):
        return True

    #用户状态
    def OnEventUserStatus(self):
        return True

    #用户段位
    def OnEventUserSegment(self):
        return True

    ########## 消息处理 ##########
    #游戏开始 
    def OnSubSendCard(self):
        cmd = CMD_S_SendAllCard()
        self.ai_user.SetGameStatus(GS_LAND_SCORE)
        self.TurnCardCount = 0
        self.TurnCardData = []
        self.CurrentLandScore = 255
        #所有扑克
        for i in range(GAME_PLAYER):
            self.game_logic.SetUserCard(i,cmd.CardData[i],NORMAL_COUNT)
        #叫牌扑克
        LandScoreCardData = cmd.CardData[self.ai_user.chair_id]
        LandScoreCardData.extend(cmd.back_data)
        self.game_logic.SetLandScoreCardData(LandScoreCardData)
        #手上扑克
        self.HandCardCount = NORMAL_COUNT
        self.HandCardData = cmd.CardData[self.ai_user.chair_id]
        self.ai_user.SortCardList(self.HandCardData)
        if self.ai_user.chair_id == cmd.current_user:
            elapse = randint(0, TIME_CALL_SCORE) + TIME_LESS
            self.ai_user.SetGameTime(IDI_CALL_SCORE, elapse)
        return True

    #用户叫分
    def OnSubCallScore(self):
        cmd = CMD_S_LandScore()
        self.CurrentLandScore = cmd.current_score
        self.BankerUser = cmd.land_user
        self.game_logic.SetBanker(cmd.land_user)
        if self.ai_user.chair_id == cmd.current_user:
            elapse = randint(0, TIME_CALL_SCORE) + TIME_LESS
            self.ai_user.SetGameTime(IDI_CALL_SCORE, elapse)
        return True        

    #庄家信息
    def OnSubGameStart(self):
        cmd = CMD_S_GameStart()
        self.ai_user.SetGameStatus(GS_LAND_PLAYING)
        self.BankerUser = cmd.land_user
        self.game_logic.SetBanker(cmd.land_user)
        self.game_logic.SetBackCard(cmd.land_user,cmd.back_card)
        if cmd.land_user == self.ai_user.chair_id:
            self.HandCardCount += cmd.back_card_count
            self.HandCardData = cmd.back_card
            self.game_logic.SortCardList(self.HandCardData,self.HandCardCount,ST_ORDER)
        #玩家设置
        if cmd.current_user == self.chair_id:                        
            elapse = randint(0, TIME_OUT_CARD) + TIME_LESS
            self.ai_user.SetGameTime(IDI_OUT_CARD, elapse)
        self.SetUserDouble(cmd.score_info)
        return True

    #用户出牌
    def OnSubOutCard(self, CmdData):
        cmd = CMD_S_OutCard()
        if(cmd.current_user == cmd.out_card_user):
            self.TurnCardCount = 0
            self.TurnCardData = []
        else:
            self.TurnCardCount = cmd.card_count
            self.TurnCardData = cmd.card_data
            self.OutCardUser = cmd.out_card_user
        if self.ai_user.chair_id==cmd.current_user:
            elapse = randint(0, TIME_OUT_CARD) + TIME_LESS
            self.ai_user.SetGameTime(IDI_OUT_CARD, elapse)
        self.ai_user.RemoveUserCardData(cmd.out_card_user,cmd.card_data)        
        return True

    #用户放弃
    def OnSubPassCard(self, CmdData):
        cmd = CMD_S_PassCard()
        if cmd.new_turn:
            self.TurnCardCount = 0
            self.TurnCardData = []
        if self.ai_user.chair_id==cmd.current_user:
            elapse = randint(0, TIME_OUT_CARD) + TIME_LESS
            self.ai_user.SetGameTime(IDI_OUT_CARD, elapse)
        return True

    #游戏结束
    def OnSubGameEnd(self):
        self.ai_user.SetGameStatus(GS_LAND_FREE)
        self.TurnCardCount = 0
        self.HandCardCount = 0
        self.TurnCardData = []
        self.HandCardData =[]
        self.ai_user.KillGameTimer(IDI_OUT_CARD)
        self.ai_user.KillGameTimer(IDI_CALL_SCORE)
        #开始设置
        elapse = randint(0, TIME_START_GAME) + TIME_LESS
        self.ai_user.SetGameTime(IDI_START_GAME, elapse)
        return True
    
    #跟、反
    def OnSubUserDouble(self):
        cmd = CMD_S_UserDouble()
        #大牌数目
        large_card_count = 0
        for card in self.game_logic.LandScoreCardData:
            if card >= 15:
                large_card_count += 1
            else:
                break
        #单牌个数
        single_card_count = self.game_logic.AnalyseSinleCardCount(self.game_logic.LandScoreCardData)
        if large_card_count>=4 and single_card_count<=4:
            if cmd.current_user == self.ai_user.chair_id or cmd.current_user2 == self.ai_user.chair_id:
                if (randint(1,2) == 1):
                    ud = CMD_C_UserDouble()
                    if self.BankerUser==self.ai_user.chair_id:
                        ud.double = 3
                    else:
                        ud.double = 2
                    self.ai_user.SendSocketData(SUB_C_USER_DOUBLE,cmd.SerializeToString())

    #倒
    def SetUserDouble(self, score_info):
        if score_info[self.ai_user.chair_id]==0:
            if (randint(1,2) == 1):
                cmd = CMD_C_UserDouble()
                cmd.double = 1
                self.ai_user.SendSocketData(SUB_C_USER_DOUBLE,cmd.SerializeToString())
        return True
            
        
    